/*
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* openUBMC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*         http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

#include "test_awm_m11p_common.h"

using namespace dev;

namespace drivers {
namespace pcie_gpu_card {
namespace innosilicon {
namespace awm_m11p_test {

// ========================= GraphicsController设备测试 =========================

TEST_F(AwmM11pAbiTest, create_awm_m11p_gpu_success) {
    // 目标：验证GraphicsController设备创建成功
    auto device_driver = m_devices["GraphicsController"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = device_driver->ctor(&m_test_service, "awm_m11p_gpu");
    ASSERT_TRUE(device != nullptr);
}

TEST_F(AwmM11pAbiTest, basic_start_stop_gpu) {
    // 目标：验证GPU设备的基本启动和停止功能
    auto device_driver = m_devices["GraphicsController"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_gpu*>(device_driver->ctor(&m_test_service, "awm_m11p_gpu_start_stop"));
    ASSERT_TRUE(device != nullptr);

    status_t start_ret = device_driver->start(device);
    EXPECT_EQ(start_ret, STATUS_OK);
    
    status_t stop_ret = device_driver->stop(device);
    EXPECT_EQ(stop_ret, STATUS_OK);
}

TEST_F(AwmM11pAbiTest, default_constructor_gpu) {
    // 目标：验证GPU设备构造函数的默认值
    auto device_driver = m_devices["GraphicsController"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_gpu*>(device_driver->ctor(&m_test_service, "awm_m11p_gpu_default"));
    ASSERT_TRUE(device != nullptr);

    EXPECT_FALSE(device->m_processor.Presence);
    EXPECT_EQ(device->m_gpu.Utilization, 0);
    EXPECT_EQ(device->m_gpu.TemperatureCelsius, 0);
}

TEST_F(AwmM11pAbiTest, init_empty_config_gpu) {
    // 目标：验证使用空配置初始化GPU设备
    auto device_driver = m_devices["GraphicsController"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_gpu*>(device_driver->ctor(&m_test_service, "awm_m11p_gpu_init_empty"));
    ASSERT_TRUE(device != nullptr);

    mc::mutable_dict config;
    mc::dict connector = create_test_connector();
    
    status_t ret = device_driver->init(device, &config, &connector);
    EXPECT_EQ(ret, STATUS_OK);
}

TEST_F(AwmM11pAbiTest, init_with_properties_gpu) {
    // 目标：验证使用含成员配置初始化GPU设备
    auto device_driver = m_devices["GraphicsController"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_gpu*>(device_driver->ctor(&m_test_service, "awm_m11p_gpu_init_props"));
    ASSERT_TRUE(device != nullptr);

    mc::mutable_dict config;
    config["bmc.dev.Processor"] = mc::dict{{"Presence", true}};
    config["bmc.dev.Gpu"] = mc::dict{{"Utilization", 50}, {"TemperatureCelsius", 75}};
    config["bmc.dev.Gpu.Power"] = mc::dict{{"PowerWatts", 150}};
    config["bmc.dev.Gpu.Status"] = mc::dict{{"ECCModeEnabled", 1}};
    
    mc::dict connector = create_test_connector();
    
    status_t ret = device_driver->init(device, &config, &connector);
    EXPECT_EQ(ret, STATUS_OK);
}

TEST_F(AwmM11pAbiTest, reset_default_properties_all_gpu) {
    // 目标：验证reset_default_properties覆盖全部字段
    auto device_driver = m_devices["GraphicsController"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_gpu*>(device_driver->ctor(&m_test_service, "awm_m11p_gpu_reset"));
    ASSERT_TRUE(device != nullptr);

    ASSERT_TRUE(device->reset_default_properties());
    EXPECT_FALSE(device->m_processor.Presence);
    EXPECT_EQ(device->m_gpu.InfoRomVersion, std::string());
    EXPECT_EQ(device->m_gpu.BuildDate, std::string());
    EXPECT_EQ(device->m_gpu.UUID, std::string());
    EXPECT_EQ(device->m_gpu.Utilization, 0);
    EXPECT_EQ(device->m_gpu.TemperatureCelsius, 0);
    EXPECT_EQ(device->m_gpu_power.PowerWatts, 0);
    EXPECT_EQ(device->m_gpu_power.PowerBrakeState, 255);
    EXPECT_EQ(device->m_gpu_power.ExternalPowerSufficient, 255);
    EXPECT_EQ(device->m_gpu_status.ECCModeEnabled, 255);
    EXPECT_EQ(device->m_gpu_status.ECCModePendingEnabled, 255);
    EXPECT_EQ(device->m_gpu_status.ResetRequired, 255);
}

TEST_F(AwmM11pAbiTest, multiple_reset_default_properties_gpu) {
    // 目标：验证多次reset_default_properties的稳定性
    auto device_driver = m_devices["GraphicsController"];
    ASSERT_TRUE(device_driver != nullptr);

    auto device = static_cast<awm_m11p_gpu*>(device_driver->ctor(&m_test_service, "awm_m11p_gpu_multiple_reset"));
    ASSERT_TRUE(device != nullptr);

    for (int i = 0; i < 3; i++) {
        EXPECT_TRUE(device->reset_default_properties());
    }
}

TEST_F(AwmM11pAbiTest, multi_instance_gpu) {
    // 目标：验证多实例创建和管理
    auto device_driver = m_devices["GraphicsController"];
    ASSERT_TRUE(device_driver != nullptr);

    std::vector<void*> devices;
    for (int i = 0; i < 3; i++) {
        auto device = device_driver->ctor(&m_test_service, ("gpu_" + std::to_string(i)).c_str());
        ASSERT_TRUE(device != nullptr);
        
        status_t start_ret = device_driver->start(device);
        EXPECT_EQ(start_ret, STATUS_OK);
        
        devices.push_back(device);
    }

    // 清理
    for (auto device : devices) {
        device_driver->stop(device);
    }
}

} // namespace awm_m11p_test
} // namespace innosilicon
} // namespace pcie_gpu_card
} // namespace drivers
